home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / fadeflip / fadeflip.c++ < prev    next >
C/C++ Source or Header  |  1996-11-11  |  11KB  |  412 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include "oglwindow.h"
  39. #include "unitsquare.h"
  40. #include "texture.h"
  41.  
  42. #include <X11/keysym.h>
  43.  
  44. #include <sys/time.h>
  45. #include <malloc.h>
  46. #include <math.h>
  47. #include <stdlib.h>
  48.  
  49. #define FADE_RED    0.0
  50. #define FADE_GREEN    0.0
  51. #define FADE_BLUE    0.0
  52.  
  53. static char def_image0[] = 
  54.   DATADIR "opengl1.128.rgb";
  55. static char def_image1[] = 
  56.   DATADIR "opengl1.128.rgb";
  57. static char def_image2[] = 
  58.   DATADIR "re_coke.rgb";
  59. static char *def_images[3];
  60.  
  61. static float fov = 40.0;
  62. static float zdist = 5.0;        // Distance eye -> origin 
  63.  
  64. static int frame = 0;            // Have square fill entire fov?
  65. static int fix_size = 0;        // Fix size of window to size
  66.                       // of first image?
  67.  
  68. static int rainbow = 0;            // Use rainbow colors for mipmaps?
  69.  
  70. static int fade = 0;            // Fill smaller mipmaps with
  71.                      // black?
  72.  
  73.  
  74. static int use_texture = 1;        // Use textures at all?
  75.  
  76. static float rotx = 0.0, roty = 0.0;    // Rotations about x and y per second
  77.  
  78. const float mouse_poll = 100000;        // How often to poll mouse
  79.  
  80. static float fadecolors[][3] = {
  81.   {1, 0, 0},
  82.   {1, 1, 0},
  83.   {0, 1, 0},
  84.   {0, 1, 1},
  85.   {0, 0, 1},
  86.   {1, 0, 1}};
  87. static int n_colors = 6;
  88.  
  89. static int paused = 0;
  90.  
  91. GLfloat matrix[16];
  92.  
  93. int n_textures;
  94.  
  95. oglwindow *window;
  96. unitsquare *square;
  97.  
  98. int win_height, win_width;
  99.  
  100. int image = 0;
  101.  
  102. /* Note - odd number display lists are the images; the even number that
  103.  * directly follows is the fade for that image */
  104.  
  105. inline float radians(float degrees)
  106. {
  107.   return ((degrees / 180.0) * M_PI);
  108. }
  109.  
  110. inline unsigned long current_time()
  111. {
  112.   struct timeval time;
  113.   gettimeofday(&time, NULL);
  114.   return (time.tv_sec * 1000000 + time.tv_usec);
  115. }
  116.  
  117. inline float transform_z(float *m) 
  118. {
  119.   return (m[10] + m[11]);
  120. }
  121.  
  122. void do_rotation(unsigned long last_time, unsigned long time)
  123. {
  124.   float elapsed_time;
  125.   float z;
  126.  
  127.   elapsed_time = (time - last_time) / 1000000.0;
  128.  
  129.   z = transform_z(matrix);
  130.  
  131.   glPushMatrix(); 
  132.   glLoadIdentity(); 
  133.   if (!paused) {
  134.     glRotatef(elapsed_time * rotx, 1, 0, 0);
  135.     glRotatef(elapsed_time * roty, 0, 1, 0);
  136.   }
  137.   glMultMatrixf(matrix);
  138.   glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  139.   glPopMatrix(); 
  140.   glMultMatrixf(matrix);
  141.  
  142.   /* If the square has flipped around so that a different face is 
  143.    * is visible, a different image should be used */
  144.   if (n_textures && z * transform_z(matrix) <= 0.0) 
  145.     image = (image + 1) % n_textures;
  146. }
  147.  
  148. unsigned long draw(unsigned long last_draw)
  149. {
  150.   unsigned long time = current_time();
  151.  
  152.   glMatrixMode(GL_PROJECTION);
  153.   glLoadIdentity();
  154.   gluPerspective (fov, 1.0, 0.01, 20.0); 
  155.  
  156.   glMatrixMode(GL_MODELVIEW);
  157.   glLoadIdentity();
  158.   gluLookAt(0, 0, zdist, 0, 0, 0, 0, 1, 0);
  159.  
  160.   glClear(GL_COLOR_BUFFER_BIT);
  161.  
  162.   glColor4ub(255, 255, 255, 255);
  163.  
  164.   glCallList(image * 2 + 1);
  165.   glCallList(image * 2 + 2);
  166.  
  167.   do_rotation(last_draw, time);
  168.  
  169.   square->draw();
  170.   
  171.   window->swapbuffers();
  172.  
  173.   return time;
  174. }
  175.  
  176. int mouse_motion(int oldmx, int oldmy, unsigned long last_time,
  177.                  int mx, int my, unsigned long time)
  178. {
  179.   float dx, dy, dt;
  180.  
  181.   dt = (time - last_time) / 1000000.0;
  182.  
  183.   // Find the mouse motion vector in screen space
  184.   dx = (float)(mx - oldmx) / (float)win_width;
  185.   dy = (float)(my - oldmy) / (float)win_height;
  186.  
  187.   rotx = dy * 180.0 / dt;
  188.   roty = dx * 180.0 / dt;
  189.  
  190.   if (rotx != 0.0 || roty != 0.0) return 1;
  191.   else return 0;
  192. }
  193.  
  194. void show_usage() 
  195. {
  196.   fprintf(stderr, "Usage:\n");
  197.   fprintf(stderr, "fadeflip [-f<field of view>] [-s<speed>] file1.rgb \
  198. [file2.rgb...]\n");
  199. }
  200.  
  201. void main(int argc, char **argv)
  202. {
  203.   Display *dpy;
  204.   XEvent event;
  205.   char buffer[5];
  206.   int bufsize = 5;
  207.   KeySym key;
  208.   XComposeStatus compose;
  209.   Window root_return, child_return;
  210.   int root_x, root_y;
  211.   unsigned int mask_return;
  212.   Window winid;
  213.  
  214.   int fname;
  215.   int width, height;
  216.   texture *texmap;
  217.   int tex_width;
  218.   unsigned long time, last_mouse_time, last_draw = 0.0;
  219.   int oldmx, oldmy, mx, my;
  220.   int button_down = 0;
  221.   int moving = 0;
  222.   int i, j;
  223.   
  224.   square = new unitsquare();
  225.   square->open();
  226.  
  227.   texmap = new texture();
  228.   texmap->open();
  229.   texmap->set_min_filter(GL_LINEAR_MIPMAP_LINEAR);
  230.   texmap->set_environment(GL_DECAL);
  231.  
  232.   fname = argc;
  233.   for (i = 1; i < argc; i++) {
  234.     if (argv[i][0] != '-') {
  235.       fname = i;
  236.       break;
  237.     }
  238.     switch(argv[i][1]) {
  239.     case 'd':                // Fade
  240.       fade = atoi(&argv[i][2]);
  241.       break;
  242.     case 'f':                // Frame
  243.       frame = 1;
  244.       break;
  245.     case 'r':
  246.       rainbow = 1;
  247.       break;
  248.     case 't':                // Use textures?
  249.       use_texture = atoi(&argv[i][2]);
  250.       break;
  251.     case 'v':                // Field of view
  252.       fov = atof(&argv[i][2]);
  253.       break;
  254.     case 'x':
  255.       fix_size = 1;
  256.       break;
  257.     case 'h':
  258.     default:
  259.       show_usage();
  260.       exit(1);
  261.       break;
  262.     }
  263.   }
  264.  
  265.   window = new oglwindow();
  266.   window->set_doublebuffer(1);
  267.   window->set_title("fadeflip");
  268.  
  269.   if (use_texture) {
  270.     n_textures = argc - fname;
  271.     if (n_textures == 0) {
  272.       n_textures = 3;
  273.       argc = 3;
  274.       fname = 0;
  275.       def_images[0] = def_image0;
  276.       def_images[1] = def_image1;
  277.       def_images[2] = def_image2;
  278.       argv = def_images;
  279.     }
  280.  
  281.     texmap->create_from_file(argv[fname]);
  282.     
  283.     if (fix_size) {
  284.       width = texmap->get_width();
  285.       height = texmap->get_height();
  286.       window->set_minsize(width, height);
  287.       window->set_maxsize(width, height);
  288.     } 
  289.   } else n_textures = 0;
  290.  
  291.   window->add_event_mask(ButtonReleaseMask);
  292.   window->open();
  293.   window->map();
  294.   window->winset();
  295.   glClear(GL_COLOR_BUFFER_BIT);
  296.  
  297.   dpy = window->get_display();
  298.   win_width = window->get_width();
  299.   win_height = window->get_height();
  300.   winid = window->get_window();
  301.  
  302.   /* Tex_width = size of unit square in pixels at given distance when 
  303.    * parallel to viewing plane */
  304.   tex_width = (int)((float)window->get_width() / 
  305.             (zdist * tan(radians(fov / 2.0))));
  306.  
  307.   for (i = 0; i < n_textures; i++) {
  308.     texmap->create_from_file(argv[fname++]);
  309.  
  310.     glNewList(i*2 + 1, GL_COMPILE);
  311.     texmap->specify_texture();
  312.     glEndList();
  313.  
  314.     glNewList(i*2 + 2, GL_COMPILE);
  315.     if (fade) {
  316.       width = texmap->get_width();
  317.       height = texmap->get_height();
  318.       height = width < height ? width : height;
  319.       for (width = 1; width < height; width *= 2);
  320.       j = 1;
  321.       width /= 2;
  322.       while (width >= tex_width) {
  323.     width /= 2;
  324.     j++;
  325.       }
  326.       while (1) {
  327.     if (rainbow) 
  328.       texmap->create_color(width, fadecolors[j%n_colors][0],
  329.                    fadecolors[j%n_colors][1], 
  330.                    fadecolors[j%n_colors][2], 1, 1);
  331.     else texmap->create_color(width, 0, 0, 0, 1, 1);
  332.     texmap->set_level(j++);
  333.     texmap->setup_texture();
  334.     texmap->specify_mipmap();
  335.     if (width == 1) break;
  336.     width /= 2;
  337.       }
  338.     }
  339.     glEndList();
  340.     texmap->pixels_free();
  341.   }
  342.  
  343.   if (frame) zdist = 1.0 / tan(radians(fov) / 2.0);    
  344.  
  345.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  346.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  347.   if (use_texture) glEnable(GL_TEXTURE_2D); 
  348.  
  349.   glMatrixMode(GL_MODELVIEW);
  350.   glLoadIdentity();
  351.   glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  352.   
  353.   while (1) {
  354.     while(((moving || button_down) && XPending(dpy)) ||
  355.     (moving == 0 && button_down == 0)) {
  356.       XNextEvent(dpy, &event);
  357.       switch(event.type) {
  358.       case Expose:
  359.         last_draw = draw(last_draw);
  360.         break;
  361.       case ConfigureNotify:
  362.         window->resize();
  363.     win_width = window->get_width();
  364.     win_height = window->get_height();
  365.         break;
  366.       case ButtonPress:
  367.     button_down = 1;
  368.     oldmx = event.xbutton.x;
  369.     oldmy = event.xbutton.y;
  370.     last_mouse_time = current_time();
  371.     break;
  372.       case ButtonRelease:
  373.     button_down = 0;
  374.     break;
  375.       case KeyPress:
  376.         XLookupString(&event.xkey, buffer, bufsize, &key, &compose);
  377.         if (key == XK_Escape) exit(0);
  378.             else if (key == XK_h || key == XK_H) {
  379.           rotx = roty = 0.0;
  380.           moving = 0;
  381.       paused = 0;
  382.           last_draw = draw(last_draw);
  383.         }
  384.         else if (key == XK_w || key == XK_W) {
  385.           rotx = roty = 0.0;
  386.           glPushMatrix();
  387.           glLoadIdentity();
  388.           glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  389.           glPopMatrix();
  390.           moving = 0;
  391.       paused = 0;
  392.           last_draw = draw(last_draw);
  393.         }
  394.     else if (key == XK_space) paused = ~paused;
  395.     break;
  396.       }
  397.     }
  398.     if (moving) time = last_draw = draw(last_draw);
  399.     else time = current_time();
  400.     if (button_down && time - last_mouse_time > mouse_poll) {
  401.       XQueryPointer(dpy, winid, &root_return, &child_return, &root_x,
  402.                     &root_y, &mx, &my, &mask_return);
  403.       moving = mouse_motion(oldmx, oldmy, last_mouse_time, mx, my, time);
  404.       oldmx = mx;
  405.       oldmy = my;
  406.       last_mouse_time = time;
  407.     }
  408.   }
  409.  
  410. }
  411.  
  412.